package com.xuliugen.demo.multithread.treadlocal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 演示弱引用GC的时候清除
 * Created by xuliugen on 2017/11/12.
 */
public class ThreadLocalWeakReferenceGCDemo {

    private static final int MAIN_THREAD_LOOP_SIZE = 20;
    private static final int THREAD_LOOP_SIZE = 100;
    private static final int MOCK_DIB_DATA_LOOP_SIZE = 2000000;
    private static ThreadLocal<List<User>> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {

        ThreadLocal<Map<Integer, String>> threadLocal1 = new ThreadLocal<>();
        Map<Integer, String> map1 = new HashMap<>();
        map1.put(1, "我是第1个ThreadLocal数据！");
        threadLocal1.set(map1);
        threadLocal1.get();

        ThreadLocal<Map<Integer, String>> threadLocal2 = new ThreadLocal<>();
        Map<Integer, String> map2 = new HashMap<>();
        map2.put(2, "我是第2个ThreadLocal数据！");
        threadLocal2.set(map2);
        threadLocal2.get();

        ThreadLocal<Map<Integer, String>> threadLocal3 = new ThreadLocal<>();
        Map<Integer, String> map3 = new HashMap<>();
        map3.put(3, "我是第3个ThreadLocal数据！");
        threadLocal3.set(map3);
        threadLocal3.get();

        mockGC();
        threadLocal1.get();
        threadLocal2.get();
        threadLocal3.get();
        mockGC();

        threadLocal3.get();
    }

    private static void mockGC() {
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_LOOP_SIZE);

        for (int i = 0; i < THREAD_LOOP_SIZE; i++) {
            executorService.execute(() -> {
                threadLocal.set(addBigList());
                System.out.println(Thread.currentThread().getName());
                threadLocal.remove();
            });
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.shutdown();
    }

    private static List<User> addBigList() {
        List<User> params = new ArrayList<>(MOCK_DIB_DATA_LOOP_SIZE);
        for (int i = 0; i < MOCK_DIB_DATA_LOOP_SIZE; i++) {
            params.add(new User("xuliugen", "password" + i, "男", i));
        }
        return params;
    }

    static class User {
        private String userName;
        private String password;
        private String sex;
        private int age;

        User(String userName, String password, String sex, int age) {
            this.userName = userName;
            this.password = password;
            this.sex = sex;
            this.age = age;
        }
    }

}
